package gz.metro.datasync.service;

import com.alibaba.fastjson.JSONObject;
import gz.metro.datasync.entity.form.UserDataForm;
import gz.metro.datasync.entity.form.UserOrgDataForm;
import gz.metro.datasync.entity.model.SyncOrgModel;
import gz.metro.datasync.entity.model.SyncOrgUserRefModel;
import gz.metro.datasync.entity.model.SyncUserModel;
import gz.metro.datasync.mapper.UserSyncMapper;
import gz.metro.datasync.utils.JdbcHelper;
import gz.metro.datasync.utils.RequestParam;
import gz.metro.datasync.utils.Result;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * @author Feily
 * @功能描述 用户增量同步数据服务类
 * @创建时间 2017-12-13
 */
@Slf4j
@Service
public class UserSyncService extends SyncService {

	@Autowired
	private UserSyncMapper userSyncMapper;

	@Autowired
	private JdbcHelper jdbcHelper;

	@Autowired
	private DataClientService dataClientService;

    /**
     * 组织用户关系列表
     */
    protected List<SyncOrgUserRefModel> userOrgRefs = new ArrayList<SyncOrgUserRefModel>();

    /**
     * 删除组织用户关系中间表SQL
     */
    protected String deleteUserOrgSyncDataSql;
    /**
     * 删除组织用户关系目标表SQL
     */
    protected String deleteUserOrgTargetDataSql;
    /**
     * 保存组织用户关系目标表SQL
     */
    protected String saveUserOrgTargetDataSql;


    /**
     * 构建函数
     */
    @PostConstruct
    public void init() throws DocumentException {
        this.syncType = "user";
        this.syncConfigDocPath = "/config/sync-user-config.xml";
        if(useCustomSql){
            this.getLastSyncTimeSql = this.getSqlContent("uuap-user-getLastSyncTime");
            this.saveTargetDataSql = this.getSqlContent("uuap-user-saveTargetData");
            this.updateTargetDataSql = this.getSqlContent("uuap-user-updateTargetData");
            this.deleteTargetDataSql = this.getSqlContent("uuap-user-deleteTargetData");
            this.deleteUserOrgTargetDataSql = this.getSqlContent("uuap-userOrg-deleteTargetData");
            this.saveUserOrgTargetDataSql = this.getSqlContent("uuap-userOrg-saveTargetData");
        }else{
            this.getLastSyncTimeSql = this.buildGetLastUpdateTimeSql();
            this.saveTargetDataSql = this.buildSaveTargetDataSql();
            this.updateTargetDataSql = this.buildUpdateTargetDataSql();
            this.deleteTargetDataSql = this.buildDeleteTargetDataSql();
            this.deleteUserOrgTargetDataSql = this.buildDeleteUserOrgTargetDataSql();
            this.saveUserOrgTargetDataSql = this.buildSaveUserOrgTargetDataSql();
        }
        //删除用户同步中间表数据SQL
        this.deleteSyncDataSql = this.getSqlContent("uuap-user-deleteSyncData");

        //删除用户组织关系同步中间表数据SQL
        this.deleteUserOrgSyncDataSql = this.getSqlContent("uuap-userOrg-deleteSyncData");

    }

    @Override
    public Result deleteSyncData() {
        log.info("deleteSyncData");

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("tenantCode", this.tenantCode);

        // 删除用户组织关系
        userSyncMapper.deleteUserOrgSyncDataSql(params);

        // 删除用户
		userSyncMapper.deleteSyncDataSql(params);

        return new Result();
    }

    @Override
    public Result saveSyncData(List<Object> syncData) {
        log.info("saveSyncData");

        // 保存用户
        List<SyncUserModel> syncUser = JSONObject.parseArray(JSONObject.toJSONString(syncData), SyncUserModel.class);
		userSyncMapper.saveBatchUser(syncUser);

        // 保存用户组织关系
        userSyncMapper.saveBatchOrgRefs(this.userOrgRefs);


        return new Result();
    }

    @Transactional
    @Override
    public Result syncTargetData() {
        log.info("syncTargetData");

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("tenantCode", this.tenantCode);

        // 删除目标表中的已删除数据
        if (this.physicallyDelete) {
            jdbcHelper.execute(this.deleteTargetDataSql,params);
        }
        // 修改目标用户数据
        jdbcHelper.execute(this.updateTargetDataSql);

        // 保存目标用户数据
        jdbcHelper.execute(this.saveTargetDataSql,params);

        // 删除目标用户组织关系数据
        jdbcHelper.execute(this.deleteUserOrgTargetDataSql,params);

        // 保存目标用户组织关系数据
        jdbcHelper.execute(this.saveUserOrgTargetDataSql,params);


        return new Result();
    }

    @Override
    public List<Object> getSyncDataList(Date lastSyncTime) {
        log.info("getSyncDataList");
        log.info("lastSyncTime:{}", lastSyncTime);

        List<Object> list = new ArrayList<Object>();

//        DataClientService service = UuapClientFactory.getDataClientService();

        RequestParam requestParam = new RequestParam();
        requestParam.setUpdateBeginDate(lastSyncTime);
        requestParam.setUpdateEndDate(new Date());

        Result<List<UserDataForm>> resultEntity = dataClientService.queryUsers(requestParam);
        if (!resultEntity.isSuccess()) {
            throw new RuntimeException(resultEntity.getMessage());
        }

        // 构建数据
        List<UserDataForm> users = resultEntity.getBusinessObject();
        for (UserDataForm userDataForm : users) {

            // 构建用户
            SyncUserModel user = new SyncUserModel();
            userDataForm.copyTo(user);
            user.setTenantCode(this.tenantCode);

            user.setSyncId(UUID.randomUUID().toString());
            user.setSyncTime(new Date());
            user.setIsSync(true);
            list.add(user);

            // 构建用户组织关系列表
            for (UserOrgDataForm userOrgDataForm : userDataForm.getOrgs()) {
                SyncOrgUserRefModel ref = new SyncOrgUserRefModel();

                ref.setOrgUserId(userOrgDataForm.getOrgUserId());
                ref.setOrgId(userOrgDataForm.getOrgId());
                ref.setIsDefaultOrg(userOrgDataForm.isDefault());
                ref.setOrderNum(userOrgDataForm.getOrderNum());

                ref.setUserId(userDataForm.getUserId());
                ref.setCreateTime(userDataForm.getCreateTime());
                ref.setCreateUserId(userDataForm.getCreateUserId());
                ref.setUpdateTime(userDataForm.getUpdateTime());
                ref.setUpdateUserId(userDataForm.getUpdateUserId());
                ref.setTenantCode(this.tenantCode);

                ref.setColumn1(userOrgDataForm.getColumn1());
                ref.setColumn2(userOrgDataForm.getColumn2());
                ref.setColumn3(userOrgDataForm.getColumn3());
                ref.setColumn4(userOrgDataForm.getColumn4());
                ref.setColumn5(userOrgDataForm.getColumn5());

                ref.setSyncId(UUID.randomUUID().toString());
                ref.setSyncTime(new Date());
                ref.setIsSync(user.getIsSync());
                this.userOrgRefs.add(ref);
            }

        }

        return list;
    }

    public List<SyncOrgUserRefModel> getUserOrgRefs() {
        return userOrgRefs;
    }

    public void setUserOrgRefs(List<SyncOrgUserRefModel> userOrgRefs) {
        this.userOrgRefs = userOrgRefs;
    }


    /**
     * 删除目标用户组织关系数据SQL
     *
     * @return
     * @throws DocumentException
     */
    public String buildDeleteUserOrgTargetDataSql() throws DocumentException {

        //根元素
        Element rootElement = this.getSyncConfigDoc().getRootElement();
        //表配置元素
        Element config = rootElement.element("userOrg");
        //表配置元素
        Element table = config.element("table");
        //主键配置元素
        Element key = config.element("key");
        //目标表名
        String targetTable = table.getText();
        //源表名
        String sourceTable = table.attributeValue("sourceTable");
        //目标主键
        String targetKey = key.getText();
        //源主键
        String sourceKey = key.attributeValue("sourceColumn");
        //sql模板
        String sql = this.fullDeleteTargetDataSqlTmpl;

        //替换参数
        sql = sql.replaceAll("#targetTable#", targetTable)
                .replaceAll("#sourceTable#", sourceTable)
                .replaceAll("#targetKey#", targetKey)
                .replaceAll("#sourceKey#", sourceKey);

        return sql;
    }

    /**
     * 保存用户组织关系目标数据
     *
     * @return
     * @throws DocumentException
     */
    public String buildSaveUserOrgTargetDataSql() throws DocumentException {

        //根元素
        Element rootElement = this.getSyncConfigDoc().getRootElement();
        //表配置元素
        Element config = rootElement.element("userOrg");
        //表配置元素
        Element table = config.element("table");
        //列配置元素
        Element columns = config.element("columns");
        //目标表名
        String targetTable = table.getText();
        //源表名
        String sourceTable = table.attributeValue("sourceTable");
        //sql模板
        String sql = this.fullSaveTargetDataqlTmpl;
        //目标列
        String targetColumns = "";
        //源列
        String sourceColumns = "";

        //循环读取配置
        for (Iterator iter = columns.elementIterator("column"); iter.hasNext(); ) {
            Element ele = (Element) iter.next();
            String sourceName = ele.attribute("sourceColumn").getText();
            String targetName = ele.getText();
            if (StringUtils.isBlank(sourceName) || StringUtils.isBlank(targetName)) {
                continue;
            }

            targetColumns += StringUtils.format(", {0}", targetName);
            sourceColumns += StringUtils.format(", {0}", sourceName);

        }

        //替换参数
        sql = sql.replaceAll("#targetTable#", targetTable)
                .replaceAll("#sourceTable#", sourceTable)
                .replaceAll("#targetColumns#", targetColumns.substring(1))
                .replaceAll("#sourceColumns#", sourceColumns.substring(1));

        return sql;
    }

}
